package com.mini.grpc.server;

import com.mini.grpc.common.MethodDescriptor;
import com.mini.grpc.common.ServiceDescriptor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

/**
 * 服务端服务定义
 * 包含服务的所有方法定义和处理器
 * 
 * @author Mini-gRPC
 */
public final class ServerServiceDefinition {
    
    private final String serviceName;
    private final Map<String, ServerMethodDefinition<?, ?>> methods;
    
    /**
     * 私有构造函数
     * 
     * @param serviceName 服务名称
     * @param methods 方法定义映射
     */
    private ServerServiceDefinition(String serviceName, Map<String, ServerMethodDefinition<?, ?>> methods) {
        this.serviceName = serviceName;
        this.methods = Collections.unmodifiableMap(new HashMap<>(methods));
    }
    
    /**
     * 获取服务名称
     * 
     * @return 服务名称
     */
    public String getServiceName() {
        return serviceName;
    }
    
    /**
     * 获取所有方法定义
     * 
     * @return 方法定义映射
     */
    public Map<String, ServerMethodDefinition<?, ?>> getMethods() {
        return methods;
    }
    
    /**
     * 根据方法名获取方法定义
     * 
     * @param methodName 方法名
     * @return 方法定义，如果不存在返回null
     */
    @SuppressWarnings("unchecked")
    public <ReqT, RespT> ServerMethodDefinition<ReqT, RespT> getMethod(String methodName) {
        return (ServerMethodDefinition<ReqT, RespT>) methods.get(methodName);
    }
    
    /**
     * 获取服务描述符
     * 
     * @return 服务描述符
     */
    public ServiceDescriptor getServiceDescriptor() {
        ServiceDescriptor.Builder builder = ServiceDescriptor.newBuilder(serviceName);
        for (ServerMethodDefinition<?, ?> methodDef : methods.values()) {
            builder.addMethod(methodDef.getMethodDescriptor());
        }
        return builder.build();
    }
    
    /**
     * 创建构建器
     * 
     * @param serviceName 服务名称
     * @return 构建器实例
     */
    public static Builder builder(String serviceName) {
        return new Builder(serviceName);
    }
    
    /**
     * 服务定义构建器
     */
    public static final class Builder {
        private final String serviceName;
        private final Map<String, ServerMethodDefinition<?, ?>> methods = new HashMap<>();
        
        private Builder(String serviceName) {
            this.serviceName = serviceName;
        }
        
        /**
         * 添加方法定义
         * 
         * @param method 方法描述符
         * @param handler 方法处理器
         * @param <ReqT> 请求类型
         * @param <RespT> 响应类型
         * @return 构建器实例
         */
        public <ReqT, RespT> Builder addMethod(
                MethodDescriptor<ReqT, RespT> method,
                ServerCallHandler<ReqT, RespT> handler) {
            if (method == null) {
                throw new IllegalArgumentException("method cannot be null");
            }
            if (handler == null) {
                throw new IllegalArgumentException("handler cannot be null");
            }
            
            String methodName = method.getFullMethodName();
            if (methods.containsKey(methodName)) {
                throw new IllegalStateException("Method already registered: " + methodName);
            }
            
            methods.put(methodName, ServerMethodDefinition.create(method, handler));
            return this;
        }
        
        /**
         * 构建服务定义
         * 
         * @return 服务定义实例
         */
        public ServerServiceDefinition build() {
            return new ServerServiceDefinition(serviceName, methods);
        }
    }
} 